package com.styytech.dadabao.widge.clippicture;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.media.ExifInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

import java.io.File;
import java.io.IOException;

/**
 * @图片的放缩
 * @移动、截图
 */
@SuppressLint("ResourceAsColor")
public abstract class ClipPictureBaseActivity extends ConstantsActivity implements
        OnTouchListener {

    /**
     * 截图后，或者旋转之后重新生成的bitmap
     */
    protected Bitmap NewBitmap;

    private int statusBarHeight = 0;// 手机屏幕状态栏的高度
    private int titleBarHeight = 0;// 手机标题栏的高度

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    /**
     * 功能：将原图片按照手机屏幕的宽高进行缩放，并填充到ImageView中<br>
     * 解决图片资源过大，一些手机出现黑屏，无法正常显示图片BUG
     */
    public void zoomPicture(ImageView iv) {
        String capturePath = getPhotoTempPath();
        if (new File(capturePath).exists()) {
            new asyncTask(iv, capturePath, this).execute(0);
        } else {
            // string-图片读取失败
            finish();
        }
    }

    /**
     * 旋转图片
     *
     * @param angle  旋转的角度
     * @param bitmap 被旋转的图片
     * @return Bitmap 重新生成的新图片
     */
    public Bitmap rotaingImageView(int angle, Bitmap bitmap) {
        // 旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.setRotate(angle);
        // matrix.postRotate(90);
        // 创建新的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }


    /**
     * 获取矩形区域内的截图
     *
     * @param clipview
     * @return Bitmap
     */
    public Bitmap getBitmap(ClipView clipview) {
        getBarHeight();// 第一步:获取保存屏幕图像的Bitmap对象；
        Bitmap screenShoot = takeScreenShot();// 第二步 得到状态栏的高度
        // 第三步 获取屏幕图像的高度
        int width = clipview.getWidth();
        int height = clipview.getHeight();
        // 创建新的Bitmap对象 并截取除了状态栏的其他区域(这里是效果图的中间那块正方形区域)；
        Bitmap finalBitmap = Bitmap.createBitmap(screenShoot,
                (width - height / 2) / 2, height / 4 + titleBarHeight
                        + statusBarHeight, height / 2, height / 2);
        return finalBitmap;
    }

    // 第一步:获取保存屏幕图像的Bitmap对象；
    protected Bitmap takeScreenShot() {
        View view = this.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        return view.getDrawingCache();
    }

    // 第二步 得到状态栏的高度
    protected void getBarHeight() {
        // 获取状态栏高度
        Rect frame = new Rect();
        this.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        statusBarHeight = frame.top;

        int contenttop = this.getWindow()
                .findViewById(Window.ID_ANDROID_CONTENT).getTop();
        // statusBarHeight是上面所求的状态栏的高度
        titleBarHeight = contenttop - statusBarHeight;
    }

    /**
     * 异步任务类
     */
    class asyncTask extends AsyncTask<Integer, Integer, String> {
        private ImageView iv;
        private String capturePath;
        private Activity activity;
        Bitmap bitmap = null;

        /**
         * 将原图片按照手机屏幕的宽高进行缩放<br>
         * 注：解决华为G750-T01 imageview 加载大分辨率图片时，不能加载BUG
         *
         * @param iv          ImageView控件
         * @param capturePath 图片路径
         * @param activity    屏幕界面
         */
        public asyncTask(ImageView iv, String capturePath, Activity activity) {
            super();
            this.iv = iv;
            this.capturePath = capturePath;
            this.activity = activity;
        }

        @Override
        protected String doInBackground(Integer... params) {

            int hight = getWindowsHeight(activity);// 获取手机界面的高
            int Width = getWindowsWidth(activity);// 获取手机界面的宽

            Options options = new Options();
            options.inJustDecodeBounds = true;// 设为true，则不会返回一个Bitmap，它仅仅返回图片的宽，高
            BitmapFactory.decodeFile(capturePath, options);
            /* 将原图片按照手机屏幕的宽高进行缩放 */
            options.inSampleSize = calculateInSampleSize(options, Width, hight); // 转换后的宽和高，具体值会有些出入
            options.inJustDecodeBounds = false;// 设为false，则会返回一个Bitmap
            bitmap = BitmapFactory.decodeFile(capturePath, options); // filePath:文件路径

            if (bitmap != null) {
                NewBitmap = bitmap;
            }
            return null;
        }

        /**
         * 这里的String参数对应AsyncTask中的第三个参数（也就是接收doInBackground的返回值）
         * 在doInBackground方法执行结束之后在运行，并且运行在UI线程当中 可以对UI空间进行设置
         */
        @SuppressLint("NewApi")
        @Override
        protected void onPostExecute(String result) {
            if (bitmap == null) {
                finish();
            } else {
                iv.setImageBitmap(bitmap);
            }
        }
    }

    /**
     * 计算原图片到用户需求图片的宽高所需要的缩放比例
     *
     * @param options
     * @param reqWidth  用户需要的图片的宽
     * @param reqHeight 用户需要的图片的高
     * @return 图片需要缩放的倍数
     */
    public static int calculateInSampleSize(Options options,
                                            int windowWidth, int windowHeight) {

        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;// 图片长宽方向缩小倍数,默认原图

        if (height > windowHeight || width > windowWidth) {
            // 计算采样率
            final int heightRatio = Math.round((float) height
                    / (float) windowHeight);
            final int widthRatio = Math.round((float) width
                    / (float) windowWidth);

            inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio; // 采样率依照最大的方向为准
        }

        return inSampleSize;
    }

    /**
     * 获取屏幕宽度
     */
    private int getWindowsWidth(Activity activity) {
        DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.widthPixels;
    }

    /**
     * 获取屏幕高度
     */
    private int getWindowsHeight(Activity activity) {
        WindowManager wm = activity.getWindowManager();
        int width = wm.getDefaultDisplay().getWidth();
        int height = wm.getDefaultDisplay().getHeight();
        return height;
    }

    // These matrices will be used to move and zoom image
    Matrix matrix = new Matrix();
    Matrix savedMatrix = new Matrix();

    // We can be in one of these 3 states
    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    int mode = NONE;
    float[] values = new float[9];

    // Remember some things for zooming
    PointF start = new PointF();
    PointF mid = new PointF();
    float oldDist = 1f;

    /**
     * 这里实现了多点触摸放大缩小，和单点移动图片的功能，参考了论坛的代码
     */
    public boolean onTouch(View v, MotionEvent event) {
        ImageView view = (ImageView) v;
        // Handle touch events here...
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix);
                // 設置初始點位置
                start.set(event.getX(), event.getY());
                // Log.d(TAG, "mode=DRAG");
                mode = DRAG;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                // Log.d(TAG, "oldDist=" + oldDist);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);
                    mode = ZOOM;
                    // Log.d(TAG, "mode=ZOOM");
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                // Log.d(TAG, "mode=NONE");
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == DRAG) {
                    // ...
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - start.x, event.getY()
                            - start.y);

                    // 记录ImageView当前的移动位置
                } else if (mode == ZOOM) {
                    if (values[0] < 0.1) {
                        // 缩放到原图的0.1倍停止缩放，并且还原到上次缩放的大小
                        matrix.set(savedMatrix);
                        return true;
                    }
                    if (values[0] > 4) {
                        // 缩放到原图的4倍停止缩放，并且还原到上次缩放的大小
                        matrix.set(savedMatrix);
                        return true;
                    }
                    float newDist = spacing(event);
                    // Log.d(TAG, "newDist=" + newDist);
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        float scale = newDist / oldDist;
                        matrix.postScale(scale, scale, mid.x, mid.y);
                    }
                }
                break;
        }
        matrix.getValues(values);// 获得matrix的值，存到values中
        view.setImageMatrix(matrix);
        return true; // indicate event was handled
    }

    /**
     * Determine the space between the first two fingers
     */
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    /**
     * Calculate the mid point of the first two fingers
     */
    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }

	/* 以下是废弃的方法 */

    /**
     * @param iv
     * @deprecated
     */
    private void makeNewBitmap(ImageView iv) {
        String path = null;
        File file = new File(path);
        /**
         * 获取图片的旋转角度，有些系统把拍照的图片旋转了，有的没有旋转
         */
        int degree = readPictureDegree(file.getAbsolutePath());
        setPictureDegreeZero(path);

        Options opts = new Options();// 获取缩略图显示到屏幕上
        opts.inSampleSize = 2;
        Bitmap cbitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), opts);

        /**
         * 把图片旋转为正的方向
         */
        Bitmap newbitmap = rotaingImageView(degree, cbitmap);
        iv.setImageBitmap(newbitmap);
    }

    /**
     * 读取图片属性：旋转的角度
     *
     * @param path 图片绝对路径
     * @return degree旋转的角度
     * @deprecated
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 将图片的旋转角度置为0
     *
     * @param path
     * @return void
     * @Title: setPictureDegreeZero
     * @date 2012-12-10 上午10:54:46
     * @deprecated
     */
    public void setPictureDegreeZero(String path) {
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            // 修正图片的旋转角度，设置其不旋转。这里也可以设置其旋转的角度，可以传值过去，
            // 例如旋转90度，传值ExifInterface.ORIENTATION_ROTATE_90，需要将这个值转换为String类型的
            // exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, "no");
            exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, ""
                    + ExifInterface.ORIENTATION_ROTATE_90);
            exifInterface.saveAttributes();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}